Por que investir?

Como esta sua situacao financeira? Caso tenha alguma reserva pode ser interessante pensar em investimentos pois a poupança já não é mais garantia de lucro no longo prazo, não acredita?

Já estamos no início de 2020 e desde 2019 já se liam notícias como esta abaixo que levam à reflexão sobre reeducação financeira pois alertam a sobre a necessidade de procurar novas oportunidades de investimento.


Fonte: https://noticias.r7.com/economia/economize/poupanca-em-baixa-exige-busca-por-novos-investimentos-em-2020-25122019


Com a finalidade de fomentar um pouco a discussão sobre investimentos, trouxe nesse post algumas sugestões e idéias de como elaborar uma carteira e otimizar as escolhas para equilibrar risco em novos investimentos combinando elementos de estatística, machine learning e programação em R.

Ao final do post criaremos um robo no telegram que coletará os dados das cotações adquiridas, aplicará o modelo Prophet do Facebook para forecast e analisará a desmontagem da carteira segundo os critérios estabelecidos e enviará mensagens para nós com uma tabela financeira automatizada via telegram como mostra na animação:



Diferenca de poupar e investir

De acordo com um especialista entrevistado pela InfoMoney:

“Poupar é guardar dinheiro para usar no futuro, comprar alguma coisa com ele. Investimento é juntar dinheiro, não mexer nele, para que este gere rendimentos e aí sim, usar os lucros mais para frente. É o recomendado para quem quer viver de renda no futuro, por exemplo” (…)
InfoMoney - Ago 2015

Ou seja, poupar é acumular agora para utilizar depois, e normalmente envolve mudança de hábitos, pois requer uma redução nos gastos pessoais e familiares, já Investir é usar esse dinheiro poupado em aplicações que rendam.

Como todo mundo sabe, não existe investimento sem risco e este risco deve ser controlado e utilizado a nosso favor de forma que gere alguma segurança financeira.

Montagem da carteira

Provamente você já ouviu essa frase alguma vez na vida e ela certamente faz sentido. Não colocar todos os ovos na mesma cesta significa que você deve diversificar o seu investimento.

Diversificar a carteira irá proteger seus investimentos diminuindo o risco pois, imagine só, você investe todo o seu dinheiro em uma empresa e ela passa por alguma crise assim seu dinheiro estará todo comprometido!

Existem diversos motivos para se diversificar a carteira mas acho que essa metáfora dos ovos já resume bem.

Como dividir a carteira?

Dependendo do risco que você deseja se expor existem muitas formas de preparar a carteira mas a idéias principal consiste em atingir um equilíbrio entre dois tipos de investimento:

  • Renda fixa: Menor exposição, menor risco (ex.: CDI, Selic e TR)
  • Renda variável: Maior exposição, maior risco (ex:Ações, Commodities, Imóveis)

Para ajudar a dividir a carteira de investimentos neste post utilizaremos a chamada Regra (ou Lei) dos 80. A estratégia é a seguinte: subtraia da sua idade o número 80. O resultado dessa conta vai indicar o percentual a ser investido em renda variável. Por exemplo, no meu caso: tenho 26 anos, portanto \(80-26 = 54\%\) deverá ser investido em renda variável. Aos 53 anos esse percentual vai cairá para a metade, \(27\%\).

A idéias principal por trás desta regra que é que a cada ano que passa, 1% do montante da renda variável deva ser direcionado para a renda fixa.

Para testar diferentes valores seguindo esta regra desenvolvi uma função que se chama montagem80() (que já está disponível no github TODO). Vejamos alguns resultaodos para diferentes cenários e vamos selecionar um para seguir com a montagem da carteira:

source("montagem80.R")

1. Entrada de R$20.000,00

montagem80(entrada = 20000, idade = 26)
## • Entrada: R$R$20.000,00
##   └─ Renda fixa:     R$9.200,00
##   └─ Renda variavel: R$10.800,00
##        (Acao + Cryptomoeda): 
##        R$9.720,00 + R$1.080,00
  1. R$ 5.000,00 em acoes
montagem80(variavel = 10800, idade = 53)
## • Entrada: R$R$40.000,00
##   └─ Renda fixa:     R$29.200,00
##   └─ Renda variavel: R$10.800,00
##        (Acao + Cryptomoeda): 
##        R$9.720,00 + R$1.080,00

Utilizaremos a primeira (1.) que esta assinalada em vermelho como exemplo, onde:

  • Entrada: R$20.000,00
  • Renda fixa: R$9.200,00
  • Renda Variavel (Acoes): R$9.720,00
  • Renda Variavel (Crypt): R$1.080,00 Note que a entrada deve ser o dobro na segunda (2.) configuração caso deseje investir R$10.800,00 (que é o valor sugerido aos 26 anos para uma entrda de R$20.000,00)

Após definir a quantidade a ser investida é hora de planejar a próxima estapa: a divessificação.

Diversificação da carteira

A diversificação é uma técnica para gestão do risco que visa distribuir o capital investido em uma variedade de investimentos dentro de da nossa carteira.

Assim, o risco do portfólio é consideravelmente reduzido pois reduzimos a volatividade e criamos um equilibrio onde um desempenho positivo de um ativo neutraliza as baixas ocorridas em outras aplicacoes. Além disso a diversificação pode ser tanto coma renda variável quanto com a renda fixa.

Mas lembre-se, não existe uma receita mais eficiente!

Renda fixa

Normalmente diversificamos nossa renda fixa também mas como gostaria de focar nas análises de renda variável utilizaremos o simulador disponivel no site https://verios.com.br/ neste link para avaliar nossa escolha:


Fonte: https://simulador-tesouro-direto.verios.com.br/


A título de exemplo, escolhi o Tesouro Prefixado 2015 (LTN), note que com essa escolha o lucro planejado seria de quase 3 mil reais nos próximos 5 anos.

Volto a lembrar que esta seleção é apenas um exemplo e existem diversas informações a serem levadas em conta ao se fazer esta escolha. Convido o leitor a procurar saber mais sobre os tipos, prós e contras do Tesouro Direto.

Renda variável

Para compor ajudar a compor a parte da cateira que de renda variável selecionei duas ações (de forma totalmente arbitrária para exemplificar neste post) que são inversamente correlacionadas baseado no excelente post "Estudo de correlação entre ações da Bolsa de Valores de São Paulo" escrito por Victor Gomes onde o autor faz um estudo de correlações das séries históricas de ações de diferentes setores.

O Bitcoin foi selecionado para completar a carteira de renda variável como um ativo de alto risco com bastante volatividade, mas por que assumir este risco?

São muitas as histórias de pessoas que ficaram milhorárias com o bitcoin pela sua valorização inesperada ao longo do tempo, como por exemplo o adolescente que ficou milionário aos 18 anos usando bitcoins após fazer aposta com os pais.

Então eu acho que 10% dessa nossa carteira (não esqueça que podemos ter mais de uma carteira) é um risco que pode valer a pena correr e por isso vou incluí-lo.

Portanto, para este exemplo consideramos:

# portifolio = c("PETR4.SA","FIBR3.SA", "BTC-USD")
portifolio = c("TUPY3.SA","ELET3.SA", "BTC-USD")

Obter dados

A aquisição das série históricas das cotações destes ativoes desde 01/01/2016 foram obtidas utilizando o pacote tidyquant que nos retorna os dados das cotações das ações informadas em formato “arrumado” (ou seja, familiar com funções do tidyverse), veja:

library(tidyquant) # aquisicao de dados financeiros
# stocks <-map_df(portifolio, ~tq_get(.x, get = "stock.prices", from = " 2016-01-01"))
# saveRDS(stocks, "stocks.rds")
stocks <- readRDS("stocks.rds")

Veja as linhas iniciais do dataset obtido:

# https://github.com/gomesfellipe/functions/blob/master/inicio_e_fim_da_base.R
stocks %>% inicio_e_fim_da_base() %>% kable2()
symbol date open high low close volume adjusted
TUPY3.SA 2016-01-04 18.549999 19.370001 18.379999 19.139999 300200 15.297645
TUPY3.SA 2016-01-05 19.59 19.59 17.82 18 273600 14.386499
TUPY3.SA 2016-01-06 17.700001 18.440001 17.700001 18.299999 203900 14.626276
TUPY3.SA 2016-01-07 18.1 18.49 18.01 18.290001 362100 14.618282
TUPY3.SA 2016-01-08 18.4 18.65 18.15 18.4 121100 14.706201
TUPY3.SA 2016-01-11 18.299999 18.59 17.719999 17.75 182000 14.186687
BTC-USD 2020-03-13 5017.831055 5838.114746 4106.980957 5563.707031 74156772074 5563.707031
BTC-USD 2020-03-14 5573.077637 5625.226563 5125.069336 5200.366211 36154506007 5200.366211
BTC-USD 2020-03-15 5201.066895 5836.64502 5169.283203 5392.314941 33997889638 5392.314941
BTC-USD 2020-03-16 5385.229492 5385.229492 4575.35791 5014.47998 45368026429 5014.47998
BTC-USD 2020-03-17 5002.578125 5371.348633 4981.90918 5225.629395 38622642935 5225.629395
BTC-USD 2020-03-18 NA NA NA NA NA NA

Existem uma série de vantagens de se trabalhar com os dados neste formato em R, veremos o porque nas próximas seções.

Arrumar e transformar

O formato tsibble é um formato moderno para se trabalhar com séries temporais trazendo a filosofia do tidyverse para os dados de séries temporais facilitando o fluxo de trabalho.

Diversos outros pacotes podem ser combinados utilizando os dados no formato do pacote tsibble como os pacotes fable e o prophet (sugiro a leitura para quem nao conhece) para aplicação de modelagem de séries temporiais.

Veja como é o fluxo ao trabalhar com objetos do tipo tsibble


Fonte: https://blog.earo.me/2018/12/20/reintro-tsibble/


library(tsibble) # series temporais arrumadas
tbl_stocks <- stocks %>% as_tsibble(key = symbol, index = date, interval="Date") 

Transformar

Após converter para tsibble, vamos preencher alguns gaps da bolsa como por exemplo os finais de semana (quando a bolsa de valores fica fechada) com o mesmo valor do dia anterior:

tbl_stocks <- 
  tbl_stocks %>% 
  fill_gaps() %>% 
  tidyr::fill(c(open, high, low, close, volume, adjusted),.direction = "down")

Com os dados arrumados vamos a algumas visualizações.

Visualizar

Vejamos qual foi o comportamento das séries históricas que coletamos desde o início de 2016:

library(forecast) # series temporais
library(fpp3)     # series temporais
d2 <- 
  tbl_stocks %>% 
  group_by(symbol) %>% 
  summarise(y = mean(close))

autoplot(tbl_stocks)+
  geom_line(aes(group = symbol), color = "black", show.legend = F) + 
  facet_wrap(~symbol, scales = "free_y", ncol = 1)+
  geom_ma(n=6*30, color = "red") + 
  theme(legend.position = "none")+
  labs(subtitle = "média móvel n = 6 meses")

A série do Bitcoin é a mais imprevisível, houve um pico em 2018 mas após isso não houve nenhum grande pico como aquele. Em breve ocorrerá o Halving (a contagem regressiva pode acompanhada neste link) que é um processo de choque de oferta e ocorre aproximadamente a cada 4 anos e pode ser uma boa oportunidade de retorno.

As duas séries da bolsa de valores não parecem ter uma corerlação muito forte, os picos ocorrem de forma alternada e isto pode ser uma caracteristica boa para a carteira pois caso uma delas entre em crise a outra poderá estar em uma fase boa.

Correlacoes

Para confirmar as conjecturas formdaas ao observar o comportamento das séries histórias (de que os picos e vales se alternam) vamos dar uma olhada nos gráficos de dispersão e coeficientes de correlação de Spearman:

points_loess <- function(data, mapping){
      ggplot(data = data, mapping = mapping) + 
      geom_point(alpha = 0.3,size=0.5) + 
      geom_smooth(method = "loess")
    }

tbl_stocks %>%
  as_tibble() %>% 
  select(symbol, date, close) %>% 
  spread(key = symbol, value = close) %>%
  GGally::ggpairs(columns = 2:4,
                  upper = list(continuous = GGally::wrap("cor", method = "spearman")),
                  lower = list(continuous =  points_loess))

Note que a relação entre TUPY3 e ELET3 não é linear e além disso a correlação entre é fraca, o que pode ser benéfico para o portifólio pois uma possível queda em uma não parece não ter tanto impacto na outra.

Além disso note que a correlação do BTC-USD com TUPY3 e ELET3 é moderada e mesmo apresentando este valores numéricos, o bitcoin é um ativo negociado em escala global e é de um setor totalmente diferente das outras ações,

Forecast com Prophet do Facebook

Poderíamos utilizar uma série de modelos estatísticos, econométricos e de machine learning utilizando tanto as funções nativas do R base ou pacote forecast quanto as funções desenvolvidas para trabalhar de maneira “arrumada” com tsibble mas resolvi fazer uma abordagem diferente neste post escolhendo o modelo disponibilizado pelo Facebook.


O Prophet é um software de código aberto disponibilizado pela equipe de Data Science do Facebook que fornece um procedimento para realização de previsões de dados de séries temporais.

Segundo a documentação oficial, (em tradução livre):

O prophet tem como “base em um modelo aditivo no qual tendências não lineares se ajustam à sazonalidade anual, semanal e diária, além de efeitos de férias. Funciona melhor com séries temporais que têm fortes efeitos sazonais e várias temporadas de dados históricos. O Profeta é robusto para a falta de dados e mudanças na tendência, e geralmente lida bem com outliers”.

Este modelo me pareceu uma boa opção para exemplificar a etapa da modelagem de séries temporais deste post. Vamos ver o que o modelo do Facebook tem a nos dizer sobre o futuro das nossas ações.

Divisão entre treino e teste em séries temporais

ASsim como em uma tarefa de machine learning que não envolvem dados temporais, no caso de séries temporais, quando desejamos avaliar o ajuste do nosso modelo também dividimos o dataset em treino e teste porém utilizamos a data como índice.

Veja como serão divididas nossas séries históricas:

  • treino: inicio da série até 19/01/20;
  • teste: de 19/01/2020 até o final da série histórica (2 meses atrás)
h = 30 * 2
data_split <- Sys.Date() - h

tbl_stocks_train <-  
  tbl_stocks %>% 
  filter(date <= data_split) %>% 
  select(symbol, date, close)

tbl_stocks_test <- 
  tbl_stocks %>%
  filter(date > data_split) %>% 
  select(symbol, date, close)

Após dividir os dados em treino e teste já estamos habilitados à utilizar o modelo. Note que, por default, o modelo espera duas colunas nomeadas como ds: data da série e y: variável target da série.

Além disso faremos uma previsão 6 meses a frente dos dados de teste para entender qual a tendência o modelo estaria adotando.

library(prophet)
library(patchwork)

prophet_results <- 
  tbl_stocks_train %>% 
  rename(ds = date, y = close) %>% 
  nest(data = c(ds, y)) %>% 
  mutate(pmodel = map(data, ~ prophet(.x, daily.seasonality=TRUE))
  )%>% 
  mutate(pprediction = map(pmodel, ~.x %>% 
                             make_future_dataframe(periods = h + 30*6) %>%
                             predict(.x,.)))

Veja os resultados do ajuste do modelo:

pmap(list(
  x = prophet_results$pprediction,
  y = split(tbl_stocks_train, tbl_stocks_train$symbol),
  z = split(tbl_stocks_test, tbl_stocks_test$symbol),
  w = prophet_results$symbol
),function(x, y, z, w){
  x %>% 
    as_tibble() %>%
    mutate(ds=as_date(ds)) %>%
    select(ds, trend, yhat, yhat_lower, yhat_upper) %>% 
    ggplot() + 
    geom_line(aes(x=ds, y=yhat, color="blue"), show.legend = F) +
    geom_line(data=y, aes(x=date, y=close, color="black"), show.legend = F) +
    geom_line(data=z, aes(x=date, y=close, color="red"), show.legend = T) +
    geom_ribbon(aes(x=ds, ymin=yhat_lower, ymax=yhat_upper), alpha=0.2)  +
    scale_x_date(#limits = c(as.Date("2018-06-01"), Sys.Date() + 30*12), 
      date_breaks = "6 month", date_labels = "%m/%Y") +
    theme_bw()+
    labs(y = w, x = "")+
    scale_colour_manual(values=c("black","blue","red"), name="", labels=c("treino","modelo","teste"))+
    theme(legend.position = c(1-0.8,1-0.2), 
          legend.background = element_rect(fill=alpha('lightgrey', 0.2)),
          legend.direction = "horizontal")
}
) %>% {.[[1]] / .[[2]] / .[[3]]}

Parece interessante..

Veja que a linha azul (modelo ajustado) se ajusta bem à linha preta (dados de treino) acompanhando a série histórica e captando algumas tendências não lineares.

Porém note que a linha azul se perde completamente da linha vermelha (dados de teste) no início de 2020 e acho isso muito razoável pois dificilmente algum modelo iría prever os efeitos de uma Pandemia utilizando apenas a série histórica do ativo.

Note ainda que a linha azul se estende até o final de 2020 (previsões para os próximos 6 meses) o que sugere que a série possuía esta tendendia positiva ao longo dos anos, segundo o modelo Prophet

Feita a interpretação dos resultados.. vamos às compras!

Comprando acoes

Após toda essa exemplicação de como podem ser feitas as análises para a elaboracao da carteira chegou a hora das compras.

Suponha que tivessemos realizado nossas compra no fechamento do dia 09/01/2020, quando os valores de fechamento das cotações eram as seguintes:

tbl_stocks %>% 
  filter(date == "2020-01-09") %>% 
  mutate(close = cell_spec(moeda_real(close), "html", color = "blue", bold = T)) %>% 
  mutate_at(c(3:5, 8), ~moeda_real(.x)) %>% 
  kable2()
symbol date open high low close volume adjusted
BTC-USD 2020-01-09 R$8.082,30 R$8.082,30 R$7.842,40 R$7.879,07 24045990465 R$7.879,07
ELET3.SA 2020-01-09 R$ 39,31 R$ 39,72 R$ 39,08 R$ 39,35 4357400 R$ 39,35
TUPY3.SA 2020-01-09 R$ 25,84 R$ 26,05 R$ 25,60 R$ 26,05 465400 R$ 26,05

Neste dia a cotação para ELET3 era R$39,35 e TUPY3 era R$26,05 e suponha que tenhamos comprado 190 lotes fracionarios de ELET3 e 90 de TUPY, totalizando R$9.821,00 (próximo ao que avíamos planejado no inicio do estudo)

Vamos guardar estes valores:

cot_inicio = c(elet = 39.35, tupy = 26.05)
qtd_inicio = c(elet = 190, tupy = 90)

Note que o valor do Bitcoin está em dólares, para obter o valor em reais (R$) daquele dia vamos utilizar a API do Mercado Bitcoin. Como não existe nenhum pacote que forneça estes dados diretamente no R, a requisição será feita normalmente via API com o pacote jsonlite:

library(jsonlite) # requisicao de api
url <- glue::glue("https://www.mercadobitcoin.net/api/BTC/day-summary/2020/01/09/")
safe_fromJSON <- safely(fromJSON, as.numeric(NA)) 
consulta <- safe_fromJSON(url)$result %>% as_tibble() 

consulta %>%
  select(-date) %>% 
  mutate_all(~moeda_real(.x)) %>%
  mutate(closing = cell_spec(closing, "html", color = "blue")) %>% 
  kable2()
opening closing lowest highest volume quantity amount avg_price
R$32.580 R$32.243,90 R$32.000 R$32.780,40 R$5.636.666,00 R$174,37 R$4.582 R$32.326,16

O preço de fechamento foi de R$32.243,90 e suponhamos que tenha sido este o valor pago no dia. (Parece que neste dia o dolar estava em torno de R$4,09)

Para completar esta carteira fictícia vamos adiquirir 0,0032 do valor de um bitcoin

cot_inicio[3] <- consulta$closing
qtd_inicio[3] <- 0.032

Portanto, ao valor de R$32.243,90 compramos 0.032 Bitcoin totalizano 1031.8048 completando nossa carteira.

Tabela financeira

Semelhante a uma planilha financeira, criaremos uma tabela financeira automatizada que receberá como input os valores da montagem e calculará automaticamente os valores do desmontagem no tempo atual utilizando dados de apis abertas.

“Aquilo que não se pode medir, não se pode melhorar”.
Físico irlandês William Thomson

Primeiro é necessário obter os valores mais recentes das cotações das acoes que compramos na bolsa e para isto será necess’rio utilizar outro pacote pois o tidyquant só fornece os dados em frequencia diária.

Utilizaremos portanto, o pacote alphavantager que fornece dados de finanças da API gratuita Alpha Vantage no formato arrumados e também foi desenvolvida pela Business Science (mesmo criados do pacote tidyquant).

Já para a coleta da cotação em tempo real do Bitcoin em reais (R$), utilizaremos novamente a api do mercado bitcoin.

# Importar dados da bolsa de valores ==================================

library(alphavantager) # api para streaming

# consulta_acoes <- map_df(portifolio[1:2], ~{
#   alphavantager::av_get(symbol = .x,
#          av_fun = "TIME_SERIES_INTRADAY",
#          interval = "1min",  # "1min", "5min", "15min", "30min" ou "60min"
#          outputsize = "compact") %>%  # "full"
#     bind_cols(stock = rep(.x, nrow(.)))
# }
# )
# saveRDS(consulta_acoes, "consulta_acoes.rds")
consulta_acoes <- readRDS("consulta_acoes.rds")

# Impotar dados do bitcoin ============================================

coin <- "BTC"
method <- "ticker"
url <- glue::glue("https://www.mercadobitcoin.net/api/{coin}/{method}/")

safe_fromJSON <- safely(fromJSON, as.numeric(NA)) 
consulta_bitcoin <- 
  safe_fromJSON(url)$result$ticker %>% 
  as_tibble() %>% 
  transmute(timestamp = lubridate::ymd_hms(as.POSIXct(date, origin="1970-01-01")),
            open, high, low, close = sell, volume = NA, stock = "BTC.BR") %>% 
  mutate_at(c('open', 'high', 'low', 'close'), ~as.numeric(.x))

# Combinar resultados das consultas ==================================

consulta_atual <- 
  bind_rows(
    consulta_acoes %>% 
      group_by(stock) %>% 
      filter(timestamp == last(timestamp)),
    consulta_bitcoin
  ) 
# Coleta concluida! ==================================================

Resultados da consulta atual (após combinar a requisição da bolsa de valores e do mercado bitcoin):

consulta_atual  %>%
  mutate_at(2:4, ~moeda_real(.x)) %>% 
  mutate(close = cell_spec(moeda_real(close), "html", color = "blue")) %>% 
  kable2()
timestamp open high low close volume stock
2020-03-19 15:54:00 R$11,32 R$11,34 R$11,29 R$11,34 510 TUPY3.SA
2020-03-19 15:54:00 R$17,50 R$17,79 R$17,42 R$17,60 23120 ELET3.SA
2020-03-19 21:50:50 R$27.855,08 R$33.000,00 R$27.351,00 R$32.139,12 NA BTC.BR

Com os valores da Montagem organizados e os valores da Desmontagem coletados em tempo real já podemos contruir nossa tabela financeira automatizada.

A tabela contem:

  • os valores de cotacão e quantidade adquiridas de cada uma no momento da montagem da carteira;
    • os valores de cada cotação no momento atual com suas respectivas quantidades disponíveis e os resultados comparando o ganho (ou perda) seguido do resultado bruto caso realize a venda agora.
    • a última coluna indica se vale a pena vender ou não aquela cotação considerando que o valor de venda é superior ao valor de compra

Veja a tabela funal com os resultados atualizados em tempo real:

porcentagem <- function(x){paste0(round(x,2), "%")} # Funcao auxiliar

# Tabela resultado
financas <- 
  tibble(
    ativo = portifolio,
    cot_inicio = cot_inicio,
    qtd_inicio = qtd_inicio,
    vol_inicio = cot_inicio * qtd_inicio,
    cot_atual = consulta_atual$close,
    qtd_atual = qtd_inicio,
    vol_atual = cot_atual * qtd_atual,
    ganho_perda = vol_atual - vol_inicio,
    resultado_bruto = ganho_perda / vol_inicio * 100
  ) %>%
  # Preparar tabela:
  mutate(
    cot_inicio = moeda_real(cot_inicio),
    cot_atual = moeda_real(cot_atual),
    vol_inicio = moeda_real(vol_inicio),
    vol_atual = moeda_real(vol_atual),
    qtd_inicio = round(qtd_inicio,4),
    qtd_atual = round(qtd_atual,4),
    `Vender?` = ifelse(ganho_perda > 0,"\u2713", "\u2718") ,
    cot_atual = cell_spec(cot_atual, "html", color = "blue"),
    ganho_perda = cell_spec(moeda_real(ganho_perda), "html",
                            color = ifelse(ganho_perda > 0, 
                                           "green", "red")),
    resultado_bruto = cell_spec(porcentagem(resultado_bruto), "html",
                                color = ifelse(resultado_bruto > 0, 
                                               "green", "red"))) %>% 
  # Exibicao
  kable(format = "html", escape = F) %>%
  kable_styling(c("striped", "bordered", "hover", "responsive"), full_width = F) %>%
  add_header_above(c(" ", "Montagem" = 3,
                     "Desmontagem / Atual" = 3, "Resultado" = 3))

financas
Montagem
Desmontagem / Atual
Resultado
ativo cot_inicio qtd_inicio vol_inicio cot_atual qtd_atual vol_atual ganho_perda resultado_bruto Vender?
TUPY3.SA R$ 39,35 190.000 R$7.476,50 R$ 11,34 190.000 R$2.154,60 R$-5.321,90 -71.18%
ELET3.SA R$ 26,05 90.000 R$2.344,50 R$ 17,60 90.000 R$1.584,00 R$ -760,50 -32.44%
BTC-USD R$32.243,90 0.032 R$1.031,80 R$32.139,12 0.032 R$1.028,45 R$ -3,35 -0.32%

Agora que já possuímos nossa requisição completa e arrumada em tempo real precisamos ter acesso a esta informação de forma dinâmica também e para isso utilizaremos o bot do telegram.

Bot Telegram

link me ajudou bastante auns anos atras e agora usei de referencia para este post



library(telegram) # conectar bot telegram

# Definir bot
bot <- TGBot$new(token = bot_token('fgstockbot'))

# Conectar ao R
bot$set_default_chat_id(bot$getUpdates()$message$chat$id[1])


report_stocks <- function(frequencia = 60) {
  # load("historico.RData")
  
  # loop infinito
  while(
    Sys.time() > lubridate::ymd_hm("2020-03-14 10:00") & # abertura
    Sys.time() < lubridate::ymd_hm(paste0(Sys.Date(), " 17:00")) # fechamento
  ) {
    
    
    # Requisicao das cotacoes atuais
    # Acoes
    consulta_acoes <- map_df(portifolio[1:2], ~{
      cat(paste0("Coletar: ", .x, "...\n"))
      av_get(symbol = .x,
             av_fun = "TIME_SERIES_INTRADAY",
             interval = "1min",  # "1min", "5min", "15min", "30min" ou "60min"
             outputsize = "compact") %>%  # "full"
        bind_cols(stock = rep(.x, nrow(.)))
    }
    ) 
    
    cat(paste0("Coletar: BTC.BR...\n"))
    # Bitcoin
    coin = "BTC"
    method = "ticker"
    url = glue::glue("https://www.mercadobitcoin.net/api/{coin}/{method}/")
    
    safe_fromJSON <- safely(fromJSON, as.numeric(NA)) 
    
    consulta_bitcoin <- 
      safe_fromJSON(url)$result$ticker %>% 
      as_tibble() %>% 
      transmute(timestamp = lubridate::ymd_hms(as.POSIXct(date, origin="1970-01-01")),
                open, high, low, close = sell, volume = NA, stock = "BTC.BR") %>% 
      mutate_at(c('open', 'high', 'low', 'close'), ~as.numeric(.x))
    
    cat(paste0("Combinar bases...\n"))
    # Combinar requisicoes
    consulta_atual <- 
      bind_rows(
        consulta_acoes %>% 
          group_by(stock) %>% 
          filter(timestamp == last(timestamp))
        ,
        consulta_bitcoin
      ) 
    
    
    # verifica se a API retornou uma lista 
    if(!is.null(consulta_atual)) {
      cat(paste0("Calcular retornos...\n"))
      # Tabela resultado
      financas <- 
        tibble(
          ativo = portifolio,
          # inicio
          cot_inicio = cot_inicio,
          qtd_inicio = qtd_inicio,
          vol_inicio = cot_inicio * qtd_inicio,
          # Desinicio / Atual
          cot_atual = consulta_atual$close,
          qtd_atual = qtd_inicio,
          vol_atual = cot_atual * qtd_atual,
          # Resultado
          ganho_perda = vol_atual - vol_inicio,
          resultado_bruto = ganho_perda / vol_inicio * 100
        )
      
      porcentagem <- function(x){paste0(round(x,2), "%")}
      
      # Exibicao
      tabela <- 
        financas  %>%
        mutate(
          cot_inicio = moeda_real(cot_inicio),
          cot_atual = moeda_real(cot_atual),
          vol_inicio = moeda_real(vol_inicio),
          vol_atual = moeda_real(vol_atual),
          qtd_inicio = round(qtd_inicio,4),
          qtd_atual = round(qtd_atual,4),
          # vol_atual = color_bar("lightgreen")(round(vol_atual, 2)),
          # vol_inicio = color_bar("lightgreen")(round(vol_inicio, 2)),
          `Vender?` = ifelse(ganho_perda > 0,"\u2713", "\u2718") , 
          ganho_perda = cell_spec(moeda_real(ganho_perda), "html",
                                  color = ifelse(ganho_perda > 0, "green", "red")),
          resultado_bruto = cell_spec(porcentagem(resultado_bruto), "html",
                                      color = ifelse(resultado_bruto > 0, "green", "red"))) %>% 
        kable(format = "html", escape = F) %>%
        kable_styling(c("striped", "bordered", "hover", "responsive"), full_width = F) %>%
        add_header_above(c(" ", "Montagem" = 3, "Desmontagem / Atual" = 3, "Resultado" = 3))
      
      save_kable(tabela, file = "table.png", self_contained = F)
      
      cat("Enviando menssagem..\n")
      bot$sendPhoto('table.png', caption = paste0("Tabela de resultados - ",Sys.time()))
      cat("Menssagem enviada!\n")
    }
    
    cat(paste0("Aguarde ", frequencia, " segundos..\n"))
    Sys.sleep(frequencia/2)
    cat(paste0("Aguarde ", round(frequencia/2,1), " segundos..\n"))
    Sys.sleep(frequencia/2)
    
  }
}

Opcções de inovação são inúmeras:

  • Programar o bot para responder a uma menssagem rápida no relógio com o valor de uma previsão
  • Acompanhar em tempo real o treinamento de um modelo
  • Desenvolver um shiny
  • Hospedar a rotina em um servidor para operacionalizar (ver post shiny TODO)